package com.hand.wfive.loginAndVip.ui

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.text.TextUtils
import android.util.Log
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.view.isVisible
import com.hand.wfive.App
import com.hand.wfive.BuildConfig
import com.hand.wfive.R
import com.hand.wfive.activity.MainActivity
import com.hand.wfive.ad.AdConfig
import com.hand.wfive.base.BaseActivity
import com.hand.wfive.loginAndVip.ApiConfig
import com.hand.wfive.loginAndVip.LoginConfig
import com.hand.wfive.loginAndVip.MD5Util
import com.hand.wfive.loginAndVip.UserManager
import com.hand.wfive.loginAndVip.WechatLogin
import com.hand.wfive.loginAndVip.model.ApiModel
import com.hand.wfive.loginAndVip.wechatpay.WechatLoginModel
import com.hand.wfive.loginAndVip.wechatpay.WechatUserInfo
import com.hand.wfive.util.click.singleClick
import com.huawei.hms.common.ApiException
import com.huawei.hms.support.account.AccountAuthManager
import com.huawei.hms.support.account.request.AccountAuthParams
import com.huawei.hms.support.account.request.AccountAuthParamsHelper
import com.huawei.hms.support.account.result.AuthAccount
import com.huawei.hms.support.api.entity.common.CommonConstant
import com.qmuiteam.qmui.alpha.QMUIAlphaTextView
import com.qmuiteam.qmui.util.QMUIDeviceHelper
import com.qmuiteam.qmui.widget.QMUITopBarLayout
import com.rxjava.rxlife.RxLife
import com.tencent.mm.opensdk.openapi.WXAPIFactory
import org.jetbrains.anko.find
import org.jetbrains.anko.toast
import rxhttp.wrapper.param.RxHttp

@SuppressLint("SetTextI18n")
abstract class LoginBaseActivity : BaseActivity() {

    protected var mIsBuy = false
    protected lateinit var mOtherLogin: ActivityResultLauncher<Intent>

    private lateinit var mHuaweiLogin: ActivityResultLauncher<Intent>

    override fun isStatusTextBlack() = true

    protected abstract fun getTopBar(): QMUITopBarLayout

    protected abstract fun loginSuccess()

    protected fun initLogin() {
        getTopBar().addLeftBackImageButton().singleClick { finish() }
        getTopBar().updateBottomSeparatorColor(Color.TRANSPARENT)
        // 是否购买VIP
        mIsBuy = intent.getBooleanExtra(LoginConfig.paramsIsBuy, mIsBuy)

        // 华为账号登录
        find<QMUIAlphaTextView>(R.id.login_huawei).isVisible =
            AdConfig.isHuawei() && QMUIDeviceHelper.isHuawei()
        mHuaweiLogin = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) {
            if (it.data == null) return@registerForActivityResult

            val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(it.data)
            if (authAccountTask.isSuccessful) {
                // 登录成功，获取到登录帐号信息对象authAccount
                huaweiLoginSuccess(authAccountTask.result)
            } else {
                // 登录失败，status code标识了失败的原因
                val statusCode = (authAccountTask.exception as ApiException).statusCode
                showNormalTip(getTopBar(),
                    "华为账号登录失败\n${LoginConfig.getHuaweiLoginStatuMsg(statusCode)}"
                )
            }
        }
        // 微信一键登录
        if (LoginConfig.WeChatAppId.isEmpty()) {
            find<QMUIAlphaTextView>(R.id.login_wechat).isVisible = false
        } else {
            val api = WXAPIFactory.createWXAPI(this, LoginConfig.WeChatAppId, false)
            api.registerApp(LoginConfig.WeChatAppId)
        }
        // 其他方式登录
        mOtherLogin = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == RESULT_OK) {
                setResult(RESULT_OK)
                finish()
            }
        }
    }

    /**** 华为账号登录 start ****/
    protected fun huaweiLogin() {
        if (!find<ImageView>(R.id.login_policy_agree).isSelected) {
            showNormalTip(getTopBar(),"请阅读并同意隐私政策和用户协议")
            return
        }

        // 1、配置登录请求参数AccountAuthParams，包括请求用户id(openid、unionid)、email、profile（昵称、头像）等。
        // 2、DEFAULT_AUTH_REQUEST_PARAM默认包含了id和profile（昵称、头像）的请求。
        // 3、如需要请求获取用户邮箱，需要setEmail();
        val authParams = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
            .createParams()
        // 使用请求参数构造华为帐号登录授权服务AccountAuthService
        val authService = AccountAuthManager.getService(this, authParams)
        // 使用静默登录进行华为帐号登录
        val task = authService.silentSignIn()
        // 静默登录成功，处理返回的帐号对象AuthAccount，获取帐号信息
        task.addOnSuccessListener { huaweiLoginSuccess(it) }
        // 静默登录失败
        task.addOnFailureListener {
            if (BuildConfig.DEBUG)
                Log.d("HuaweiLogin", "huawe login fail: ${it.message}")

            if (it is ApiException) {
                // 使用getSignInIntent()方法进行前台显式登录
                val signInIntent = authService.signInIntent
                // 如果应用是全屏显示，即顶部无状态栏的应用，需要在Intent中添加如下参数：
                signInIntent.putExtra(CommonConstant.RequestParams.IS_FULL_SCREEN, true)
                mHuaweiLogin.launch(signInIntent)
            } else {
                showNormalTip(getTopBar(),"华为账号登录失败")
            }
        }
    }

    private fun huaweiLoginSuccess(authAccount: AuthAccount) {
        // 获取帐号信息
        if (BuildConfig.DEBUG) {
            Log.d("HuaweiLogin", "display name: ${authAccount.displayName}")
            Log.d("HuaweiLogin", "unionid: ${authAccount.unionId}")
            Log.d("HuaweiLogin", "openid: ${authAccount.openId}")
        }
        showLoading("正在登录")
        register(
            authAccount.displayName, authAccount.openId, authAccount.openId,
            UserManager.LoginType_huawei
        )
    }
    /**** 华为账号登录 end ****/

    /**** 微信登录 start ****/
    protected fun wechatLogin() {
        if (!find<ImageView>(R.id.login_policy_agree).isSelected) {
            showNormalTip(getTopBar(),"请阅读并同意隐私政策和用户协议")
            return
        }
        WechatLogin.init(this, LoginConfig.WeChatAppId)
        WechatLogin.getInstance().wechatLogin(object : WechatLogin.WechatLoginResultCallBack {
            override fun onSuccess(code: String) {
                getLoginMsgFromWx(code)
            }

            override fun onError() {
                showNormalTip(getTopBar(),"登录失败")
            }

            override fun onCancel() {
                showNormalTip(getTopBar(),"用户取消")
            }
        })
    }

    private fun getLoginMsgFromWx(code: String) {
        showLoading("正在登录")
        val url = String.format(
            "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
            LoginConfig.WeChatAppId, LoginConfig.WechatAppSecret, code
        )
        RxHttp.get(url)
            .asClass(WechatLoginModel::class.java)
            .to(RxLife.toMain(this))
            .subscribe({ response ->
                getLoginNickname(response.openid, response.access_token)
            }, {
                hideLoading()
                showNormalTip(getTopBar(),"登录失败，请重试")
            })
    }

    private fun getLoginNickname(openId: String, ACCESS_TOKEN: String) {
        val url = String.format(
            "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",
            ACCESS_TOKEN, openId
        )
        RxHttp.get(url)
            .asClass(WechatUserInfo::class.java)
            .to(RxLife.toMain(this))
            .subscribe({ response ->
                if (response.errcode == null || response.errcode.isEmpty()) {
                    register(
                        response.nickname, response.openid, response.openid,
                        UserManager.LoginType_wechat
                    )
                } else {
                    hideLoading()
                    showNormalTip(getTopBar(),"登录失败，请重试")
                }
            }, {
                hideLoading()
                showNormalTip(getTopBar(),"登录失败，请重试")
            })
    }
    /**** 微信登录 end ****/

    /**** 注册 ****/
    protected fun register(
        nickName: String, username: String, password: String, loginType: String,
    ) {
        val passwordMd5 = MD5Util.getPasswordMd5(password)
        RxHttp.postForm(ApiConfig.register)
            .add("appid", LoginConfig.AppId)
            .add("username", username)
            .add("pwd", passwordMd5)
            .add("loginType", loginType)
            .add("nickName", nickName)
            .add("appname", getString(R.string.app_name))
            .add("packageName", App.getContext().packageName)
            .asClass(ApiModel::class.java)
            .to(RxLife.toMain(this))
            .subscribe({ apiModel ->
                if (apiModel.code == ApiConfig.SUCCESSCODE) {
                    hideLoading()
                    loginSuccess()
                    toast("登录成功")
                    val user = apiModel.obj
                    user.password = passwordMd5
                    UserManager.getInstance().saveUser(user)
                    MainActivity.show(mContext)
                    if (mIsBuy && !UserManager.getInstance().isVip) {
                        VipCenterActivity.show(mContext)
                    }
                    setResult(RESULT_OK)
                    finish()
                } else if (apiModel.code == ApiConfig.USEREXISTCODE) {
                    login(username, password, loginType)
                } else {
                    hideLoading()
                    if (TextUtils.isEmpty(apiModel.msg)) {
                        showNormalTip(getTopBar(),"网络异常，请重试！")
                    } else {
                        showNormalTip(getTopBar(),apiModel.msg)
                    }
                }
            }, {
                hideLoading()
                showNormalTip(getTopBar(),"网络异常，请重试！")
            })
    }

    /**** 登录 ****/
    protected fun login(name: String, password: String, loginType: String) {
        val passwordMd5 = MD5Util.getPasswordMd5(password)
        RxHttp.postForm(ApiConfig.login)
            .add("appid", LoginConfig.AppId)
            .add("username", name)
            .add("pwd", passwordMd5)
            .add("loginType", loginType)
            .add("appname", getString(R.string.app_name))
            .add("packageName", App.getContext().packageName)
            .asClass(ApiModel::class.java)
            .to(RxLife.toMain(this))
            .subscribe({ apiModel ->
                hideLoading()
                if (apiModel.code == ApiConfig.SUCCESSCODE) {
                    loginSuccess()
                    toast("登录成功")
                    val user = apiModel.obj
                    user.password = passwordMd5
                    UserManager.getInstance().saveUser(user)
                    MainActivity.show(mContext)
                    if (mIsBuy && !UserManager.getInstance().isVip) {
                        VipCenterActivity.show(mContext)
                    }
                    setResult(RESULT_OK)
                    finish()
                } else {
                    if (TextUtils.isEmpty(apiModel.msg)) {
                        showNormalTip(getTopBar(),"网络异常，请重试！")
                    } else {
                        showNormalTip(getTopBar(),apiModel.msg)
                    }
                }
            }, {
                hideLoading()
                showNormalTip(getTopBar(),"登录失败")
            })
    }
}